package com.atguigu.starter.redisson;

import com.atguigu.starter.redisson.properties.BloomFilterProperties;
import com.atguigu.starter.redisson.properties.BloomProperty;
import org.redisson.Redisson;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

/**
 * @author 钟涛
 * @version 1.0
 * @description: redisson的自动配置类
 * @date 2021/12/14 19:35
 */
//在RedisAutoConfiguration自动配置类配置好，开启此类的配置
@AutoConfigureAfter(RedisAutoConfiguration.class)
@Configuration
@EnableConfigurationProperties(BloomFilterProperties.class)
public class RedissonAutoConfiguration {
    //redisson客户端
    @Autowired
    private RedisProperties redisProperties;

    private int timeout = 3000;
    private int connectionPoolSize = 64;
    private int connectionMinimumIdleSize = 10;
    private int pingConnectionInterval = 60000;
    private static String ADDRESS_PREFIX = "redis://";

    @Bean
    @ConditionalOnMissingBean
    public RedissonClient redissonSingle() {
        Config config = new Config();
        if (StringUtils.isEmpty(redisProperties.getHost())) {
            throw new RuntimeException("host is  empty");
        }
        SingleServerConfig serverConfig = config.useSingleServer()
                .setAddress(ADDRESS_PREFIX + redisProperties.getHost() + ":" + redisProperties.getPort())
                .setTimeout(this.timeout)
                .setPingConnectionInterval(pingConnectionInterval)
                .setConnectionPoolSize(this.connectionPoolSize)
                .setConnectionMinimumIdleSize(this.connectionMinimumIdleSize);
        if (!StringUtils.isEmpty(redisProperties.getPassword())) {
            serverConfig.setPassword(redisProperties.getPassword());
        }
        // RedissonClient redisson = Redisson.create(config);
        RedissonClient client = Redisson.create(config);

        return client;
    }

    @ConditionalOnProperty(prefix = "service.bloom", name = "enable",havingValue = "true",matchIfMissing = false)
    @Bean("skuBloomFilte")
    public RBloomFilter<Object> skuBloomFilte(BloomFilterProperties properties) {
        /**
         * 这里再调一点redissonSingle方法，获取的对象也是之前ioc容器创建的对象
         * 1.如果一个类上，标注了@Configuration,SpringBoot知道此类是个配置类
         * 2. 配置类的boolean proxyBeanMethods() default true;即此属性默认为true,表示配置类在ioc容器中也是一个代理对象
         * 3.调用redissonSingle方法，相当于代理对象会对此方法进行拦截增强
         * 4.@Bean的方法,任何时候的调用逻辑为:
         *     4.1 先看ioc容器中有没有此方法返回类型的组件，如果有，用ioc容器中的，
         *
         *     4.2 没有，就调用方法逻辑创建一个，然后返回，并放入容器中.
         */
//        System.out.println("starter的sku开始....");
        RedissonClient client = redissonSingle();
        BloomProperty skuProperty = properties.getConfig().get("sku");

        RBloomFilter<Object> bloomFilter = client.getBloomFilter(skuProperty.getBloomName());
        //先初始化
        boolean b = bloomFilter.tryInit(skuProperty.getInsertions(), skuProperty.getFalseProbability());
//        if(b){
//            //布隆过滤器第一次初始化成功
//            //TODO 把Sku的所有数据查出来放在不隆重
//        }else{
//            //布隆过滤器已经存在了
//        }
        return bloomFilter;
    }

    @ConditionalOnProperty(prefix = "service.bloom", name = "enable",havingValue = "true",matchIfMissing = false)
    @Bean("spuBloomFilte")
    public RBloomFilter<Object> spuBloomFilte(BloomFilterProperties properties) {
        /**
         * 这里再调一点redissonSingle方法，获取的对象也是之前ioc容器创建的对象
         * 1.如果一个类上，标注了@Configuration,SpringBoot知道此类是个配置类
         * 2. 配置类的boolean proxyBeanMethods() default true;即此属性默认为true,表示配置类在ioc容器中也是一个代理对象
         * 3.调用redissonSingle方法，相当于代理对象会对此方法进行拦截增强
         * 4.@Bean的方法,任何时候的调用逻辑为:
         *     4.1 先看ioc容器中有没有此方法返回类型的组件，如果有，用ioc容器中的，
         *
         *     4.2 没有，就调用方法逻辑创建一个，然后返回，并放入容器中.
         */
//        System.out.println("starter的spu开始....");
        RedissonClient client = redissonSingle();
        BloomProperty spuProperty = properties.getConfig().get("spu");

        RBloomFilter<Object> bloomFilter = client.getBloomFilter(spuProperty.getBloomName());
        //先初始化
        boolean b = bloomFilter.tryInit(spuProperty.getInsertions(), spuProperty.getFalseProbability());
//        if(b){
//            //布隆过滤器第一次初始化成功
//            //TODO 把Sku的所有数据查出来放在不隆重
//        }else{
//            //布隆过滤器已经存在了
//        }
        return bloomFilter;
    }
}
